#define _FILE_OFFSET_BITS 64
#define _LARGEFILE_SOURCE
#define __USE_LARGEFILE

#include "ppd.h"
#include "Utiles.h"


pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
sem_t sem_pedidos;
pid_t cpid;

#define SOCK_PATH "/../Consola/connect_socket"


int main(int argc, char *argv[]) {


	int file; //, len, sockEscucha;
	//struct sockaddr_un local, remote;
	float tiempo = 0;
	//signal(SIGINT, exeConsola);
	system("clear");
	char *pathConsola;
	char *msj = (char *) malloc(sizeof(char) * 500);

	sem_init(&sem_pedidos, 0, 0);
	//inicializacion(&listaPedidos);
	//inicializacionNStep(&listaPedidosNStep);

	pathConsola = (char *) malloc(sizeof(char) * 500);
	signal(SIGINT, ( __sighandler_t)finPPD);
	cargarConfiguracion(&stPPD);
	iniciarLog("ppdLog.txt");
	log("ppdLog.txt", "PPD", "INFO", "Inicia el proceso PPD");
	//printf("path: %s\n", stPPD.szPathConsola);
	//Hago fork y exec para el proceso consola
	sprintf(pathConsola, "%s/PConsola", stPPD.szPathConsola);
	//printf("path: %s\n", pathConsola);

	pthread_t tid;
	pthread_create(&tid, NULL, (void *) &consola, pathConsola);
	/* Creo el thread que manejara la consola */

	stPPD.iSocketEscucha = 0;
	stPPD.sectorActual = 0;
	stPPD.cantSectoresEscritos =0;

	printf(
			"=====================================================================\n");
	printf("\t\t Proceso Planificador de Disco (PPD)\n IP: %s \nPUERTO: %i\n",
			stPPD.szIpPPD, stPPD.iPuertoPPD);
	printf(
			"=====================================================================\n");

	printf(
			"IPRemoto: %s\nPuertoRemoto: %i\nAlgoritmo: %s\nPuerto PPD: %i\nFLAG: %i\n"
					"ID: %s\nCilindro: %i\nHead: %i\nSector: %f\nT.Lectura: %f\nT.Escritura: %i\n"
					"RPM: %i\nT.Salto: %i\nPath: %s\n\n", stPPD.szIpRemoto,
			stPPD.iPuertoRemoto, stPPD.cAlgoritmo, stPPD.iPuertoPPD,
			stPPD.iFlag, stPPD.szIdPPD, stPPD.iCilindro, stPPD.iHead,
			stPPD.iSector, stPPD.iTiempoLectura, stPPD.iTiempoEscritura,
			stPPD.iRPM, stPPD.iTiempoSalto, stPPD.szPath);

	struct stat fileInfo;
	if ((file = open(stPPD.szPath, O_RDWR)) > 0)
	{
		if(fstat(file,&fileInfo)==-1)
			perror("fstat");
		long tamanio;

//		lseek (file , 0 , SEEK_END);
//
//			tamanio = ftell (file);
//			if(tamanio==-1)
//				perror("ftell:");
//			rewind (file);
			stPPD.filesize=fileInfo.st_size;
		//stPPD.filesize = fileInfo.st_size;
		//stPPD.filesize = tamanioDisco();
//		log("ppdLog.txt", "PPD", "ERROR", stPPD.filesize);
	}
	else {
		//printf("Error al intentar abrir el archivo FAT32 \n");
		log("ppdLog.txt", "PPD", "ERROR", "Error al intentar abrir el archivo");
	}

	if ((stPPD.ArchivoEnDisco = mmap(0, stPPD.filesize, PROT_READ | PROT_WRITE
			, MAP_SHARED, file, 0)) == (void *) -1) {
		//printf("Error mapeando del archivo \n");
		log("ppdLog.txt", "PPD", "ERROR",
				"Error al intentar mappear el archivo en memoria");
	}

	//ST_SECTOR buffer;
	//memcpy(buffer, stPPD.ArchivoEnDisco, sizeof(ST_SECTOR));
	//printf("Buffer: %u\n", buffer);
	//return 0;

	if (posix_madvise(stPPD.ArchivoEnDisco, 0, POSIX_MADV_RANDOM) != 0) {
		//printf("Error al intentar definir el comportamiento del archivo \n");
		log("ppdLog.txt", "PPD", "ERROR",
				"Error al intentar definir el comportamiento del archivo");
	}

	stPPD.sectoresTotales = (int) stPPD.iCilindro * (int) stPPD.iSector;

	//7200 rev ---- 1min = 60secs = 60000ms
	//1 rev --- 60000/7200ms = 8ms aprox
	tiempo = 60000 / (int) stPPD.iRPM;
	//8ms / cantidad de sectores (totales del disco) = tiempo entre sectores
	stPPD.tiempoEntreSectores = tiempo / stPPD.sectoresTotales;

	stPPD.iTiempoEscritura = stPPD.iTiempoEscritura / 1000;
	stPPD.iTiempoLectura = stPPD.iTiempoLectura / 1000;
	//Pruebas();
	/*int s=0;
	 char* buffer=(char*)malloc(512);

	 strcpy(buffer, "hola como va");

	 s = EscribirSector(buffer, 5);
	 if (s!=0)
	 printf("error al escribir\n");
	 strcpy(buffer, leerSector(5));
	 printf("Info Leida: %s\n", buffer);*/

	//printf("modo: %s\n", stPPD.modo);
	//printf("PathConsola: %s\n", pathConsola);
	//cargarConfiguracion(&stPPD);
	if (strcmp(stPPD.modo, "LISTEN") == 0)
		manejoPPDListen();
	else
		manejoPPDConnect();

//	//kill(cpid);
//	if (msync(stPPD.ArchivoEnDisco, filesize, MS_SYNC) < 0) {
//		printf("Error al querer sincronizar el disco\n\n");
//		log("ppdLog.txt", "PPD", "ERROR",
//				"Error al querer sincronizar el disco");
//	}
	cerrarDisco();

	log("ppdLog.txt", "PPD", "INFO", "se cerro la consola del PPD");
	sprintf(msj, "kill -9 %d", cpid);
	free(msj);

	printf("Fin del proceso\n\n");
	log("ppdLog.txt", "PPD", "INFO", "Se cerró el proceso PPD");

	return 0;
}

int manejoPPDListen() {
	fd_set maestroLecturaFD, descLecturaFD, maestroEscrituraFD, descEscrituraFD;
	int i = 0, rta; //iRtaSelect,
	ST_NIPC stCabecera;
	ST_PEDIDOS_INFO info;
	char *p;
	int iSocketNuevo;
	pthread_t threadListaPedidos; //threadConsola,
	int iMaxDescriptor = 0;
	char *mensajeLog;
	//char cSector[1000000];
	mensajeLog = (char *) malloc(sizeof(char) * 250);
	int a = 0; //cantidad=0,
	ST_RESPUESTA rtaSector;

	if ((stPPD.iSocketEscucha = generarSocketEscucha()) != -1)
		log("ppdLog.txt", "PPD", "INFO", "Se genero el socket de escucha");
	else
		log("ppdLog.txt", "PPD", "ERROR",
				"Error al generar el socket de escucha");

	FD_ZERO( &maestroLecturaFD);
	FD_ZERO( &descLecturaFD);
	FD_ZERO( &maestroEscrituraFD);
	FD_ZERO( &descEscrituraFD);

	FD_SET( stPPD.iSocketEscucha, &maestroLecturaFD);
	MAXDESC( iMaxDescriptor, stPPD.iSocketEscucha);
	/*Establezco el nuevo descriptor maximo*/

	//printf("a\n");
	//pthread_create(&threadConsola, NULL, (void *) &consola, NULL);
	pthread_create(&threadListaPedidos, NULL, (void *) &ManejoColaPedidos,
			NULL);

	//printf("Estoy en el listen esperando peticiones\n");
//	iSocketNuevo = atiendeNuevaConexion();
	//printf("antes del while\n");
	int maxAux=0;
	while (1) {

		descLecturaFD = maestroLecturaFD;
		maxAux=iMaxDescriptor;
		a = select(iMaxDescriptor + 1, &descLecturaFD, NULL, NULL, NULL);
		if(a!=-1)
		{
			//printf("Despu'es de aceptar, espero envio de datos");
			for (i = 0; i <= maxAux; i++) {
				if (FD_ISSET(i, &descLecturaFD)) {
					if (i != stPPD.iSocketEscucha) {
						if ((rta = recv(i, (void *) &stCabecera, sizeof(ST_NIPC), MSG_WAITALL)) < 0) {
							log("ppdLog.txt", "PFD", "INFO", "Se cerro el socket del pfs");
							perror("error recibiendo sector");
							//printf("Cierro el socket %d por error en el recv\n", i);
							close(i);
							FD_CLR(i, &maestroLecturaFD);
							//return -4;
						} else {
							if (rta == 0) {
								log("ppdLog.txt", "PFD", "INFO", "Se cerro el socket del pfs");
								//printf("Cierro el socket %d el recv dio 0 \n", i);
								close(i);
								FD_CLR(i, &maestroLecturaFD);
								//perror("error recibiendo sector");
							} else {
								//if (rta != sizeof(ST_NIPC))
									//printf("error recv: recibi %d y deberia recibir %d \n", rta, sizeof(ST_NIPC));
								//printf("pay: %s con size: %d socket %d\n", stCabecera.szPayload, stCabecera.lPayload, i);
								/* aca pregunta por el tipo de mensaje*/
								if (stCabecera.ucType == WRITESECTOR)
								{
									/*if (recv(i, (void *) &rtaSector,
											sizeof(ST_RESPUESTA), MSG_WAITALL)
											< 0) {
										close(i);
										log("ppdLog.txt", "PFD", "INFO",
												"Se cerro el socket del pfs");
										perror("error recibiendo sector");
										//								return -4;
									}*/

									//printf("recibi writesector\n");
									info.TipoPedido = WRITESECTOR;
									//p=strtok(stCabecera.szPayload,"|");
									info.sector = stCabecera.sector;
									info.prioridad = 1;
									//p=strtok(NULL,"|");
									//strcpy(info.buffer, p);
									memcpy(info.buffer, stCabecera.buffer, sizeof(ST_SECTOR));
									sprintf(mensajeLog,"Nueva peticion del PFS: Escritura del sector %d",info.sector);
									log("ppdLog.txt", "PFD", "INFO",mensajeLog);
								} else {
									if (stCabecera.ucType == GETSECTOR)
									{
										//printf("recibi readsector %d\n", stCabecera.sector);
										//printf("Me llego un get sector\n");
										//p = strtok(stCabecera.sector, "|");
										info.sector = stCabecera.sector;
										//strcpy(info.buffer, "");
										memset(info.buffer, 0, sizeof(ST_SECTOR));
										info.TipoPedido = GETSECTOR;
										info.prioridad = 2;
										sprintf(mensajeLog, "Nueva peticion del PFS: Lectura del sector %d", info.sector);
										log("ppdLog.txt", "PFD", "INFO", mensajeLog);
									}
								}

								pthread_mutex_lock(&mutex1);
								info.socketPedido = i;
								if (strcmp(stPPD.cAlgoritmo, "SSTF") == 0) {
									if (CargoElementoEnLista(info) != 0) {
										log(
												"ppdLog.txt",
												"PFD",
												"ERROR",
												"Error al cargar el elemento en la lista");
									}
								} else {
									if (CargoElementoEnListaNStep(info) != 0) {
										log(
												"ppdLog.txt",
												"PFD",
												"ERROR",
												"Error al cargar el elemento en la lista");
										//CargoElementoEnListaAlFinalNStep(listaPedidosNStep);
										//CargoElementoEnListaNStep(info);
									}
								}
								pthread_mutex_unlock(&mutex1);
								sem_post(&sem_pedidos);
							}
							//sectoresPedidos();
						}
					} else {
						iSocketNuevo = atiendeNuevaConexion();
						FD_SET(iSocketNuevo, &maestroLecturaFD);
						MAXDESC( iMaxDescriptor, iSocketNuevo);
						//printf("socket creado %d \n", iSocketNuevo);
						//printf("socket maximo %d \n", iMaxDescriptor);
					}
				}
			}
		}
		else
		{
			perror("select:");
		}

	}
	//		descLecturaFD = maestroLecturaFD;
	//		a = select( iMaxDescriptor + 1, &descLecturaFD, NULL, NULL, NULL );
	//
	//		for(i = 0; i <= iMaxDescriptor; i++)
	//		{
	//
	//			if(FD_ISSET(i, &descLecturaFD))
	//			{
	//				if (i > iSocketNuevo)
	//				{
	//					if ((iSocketNuevo = atiendeNuevaConexion())!=0)
	//					{
	//						printf("socketNuevo:%d\n",iSocketNuevo);
	//						FD_SET(iSocketNuevo, &maestroLecturaFD); /* lo mandamos al maestro */
	//
	//						if (iSocketNuevo > iMaxDescriptor) /* actualizamos maximo */
	//							MAXDESC( iMaxDescriptor, iSocketNuevo);
	//					}else
	//						log( "ppdLog.txt", "PFD", "ERROR","Conexion con el PFS Rechazada");
	//
	//				}
	//				else
	//				{
	//					memset(stCabecera.szPayload,'\0',600);
	//					stCabecera.lPayload =0;
	//					p=(char *)malloc(sizeof(char)*600);
	//					if( recv( i, (void *) &stCabecera, sizeof(ST_NIPC), 0) < 0 )
	//					{
	//						close( stPPD.iSocketEscucha );
	//						log( "ppdLog.txt", "PFD", "INFO","Se cerro el socket del pfs");
	//						perror("error recibiendo sector");
	//						return -4;
	//					}
	//					cantidad++;
	//					printf("cantidad de pedidos: %i\n",cantidad);
	//					printf("pay: %s con size: %d\n", stCabecera.szPayload, stCabecera.lPayload);
	//					/*existe en la bolsa de conexiones, trabajo segun la peticion*/
	//					//printf("Recibi correctamente peticion del PFS\n");
	//					if (stCabecera.ucType!=PFSCERRADO)
	//					{
	//					//	printf("pay: %s con size: %d\n", stCabecera.szPayload, stCabecera.lPayload);
	//						/*p=strtok(stCabecera.szPayload,"|");
	//						strcpy(cSector, p);
	//						info.sector=atoi(cSector);
	//
	//						if(stCabecera.ucType==WRITESECTOR)
	//						{
	//							//printf("recibi writesector\n");
	//							info.TipoPedido = WRITESECTOR;
	//							info.prioridad = 1;
	//							p=strtok(NULL,"|");
	//							strcpy(info.buffer, p);
	//							sprintf(mensajeLog, "Nueva peticion del PFS: Escritura del sector %d", info.sector);
	//							log( "ppdLog.txt", "PFD", "INFO", mensajeLog);
	//						}else
	//						{
	//							if(stCabecera.ucType==GETSECTOR)
	//							{
	//								//printf("recibi readsector\n");
	//								printf("Me llego un get sector\n");
	//								strcpy(info.buffer, "");
	//								info.TipoPedido = GETSECTOR;
	//								info.prioridad = 2;
	//								sprintf(mensajeLog, "Nueva peticion del PFS: Lectura del sector %d", info.sector);
	//								log( "ppdLog.txt", "PFD", "INFO", mensajeLog);
	//							}
	//						}
	//
	//						pthread_mutex_lock( &mutex1 );
	//						info.socketPedido = i;
	//						if (strcmp(stPPD.cAlgoritmo, "SSTF")==0)
	//						{
	//							if (CargoElementoEnLista(info)!=0)
	//							{
	//								log( "ppdLog.txt", "PFD", "ERROR","Error al cargar el elemento en la lista");
	//							}
	//						}else
	//						{
	//							if (CargoElementoEnListaNStep(info)!=0)
	//							{
	//								log( "ppdLog.txt", "PFD", "ERROR","Error al cargar el elemento en la lista");
	//								//CargoElementoEnListaAlFinalNStep(listaPedidosNStep);
	//								//CargoElementoEnListaNStep(info);
	//							}
	//						}
	//						pthread_mutex_unlock( &mutex1 );
	//						sectoresPedidos();*/
	//					}
	//				}
	//			}
	//		}
	//free(p);
	free(mensajeLog);
return 0;
}

int manejoPPDConnect() {
struct sockaddr_in dest_addr;
//int 	socketPraid;
fd_set cjtoTemporal, maestroLecturaFD;
fd_set cjtoMaestro;
int socketMax;
//int 	nbytes;
//int 	n;
#define STDIN  0
ST_NIPC stCabecera;
int iMaxDescriptor = 0;
ST_RESPUESTA rtaSector;
char *p;
//int iSocketNuevo;
pthread_t threadListaPedidos; //threadConsola,
ST_PEDIDOS_INFO info;
char *mensajeLog;
int valorRetorno;
mensajeLog = (char *) malloc(sizeof(char) * 250);

//stPPD.iSocketRaid = (int)CreaSocketPraid(stPPD.szIpRemoto, stPPD.iPuertoRemoto);

if ((stPPD.iSocketRaid = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
	perror("socket");
	return 1;
}

FD_ZERO(&cjtoMaestro);
FD_ZERO(&cjtoMaestro);
FD_SET(STDIN, &cjtoMaestro);
FD_SET(stPPD.iSocketRaid, &cjtoMaestro);

dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(stPPD.iPuertoRemoto);
dest_addr.sin_addr.s_addr = inet_addr(stPPD.szIpRemoto);

socketMax = stPPD.iSocketRaid;

memset(&(dest_addr.sin_zero), '\0', 8);
if (connect(stPPD.iSocketRaid, (struct sockaddr *) &dest_addr, sizeof(struct sockaddr)) == -1) {
	//printf("ERROR: Al intentar conectar con el PRAID\n");
	perror("error conexion con PRAID");
	return 1;
}

/* Envio solicitud de conexion */
stCabecera.ucType = HANDSHAKE;
sprintf(stCabecera.buffer, "%s|%d|%d|%d|", stPPD.szIdPPD, stPPD.iCilindro,stPPD.iHead, stPPD.iSector);
stCabecera.lPayload = sizeof(stCabecera.buffer);

if (send(stPPD.iSocketRaid, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL) < 0)
	log("ppdLog.txt", "PPD", "ERROR", "Error al querer enviar handshake");

/* Respuesta a la solicitud de conexion */

if (recv(stPPD.iSocketRaid, (void *) &stCabecera, sizeof(ST_NIPC), MSG_WAITALL)
		< 0)
	log("ppdLog.txt", "PPD", "ERROR",
			"Error al recibir respuesta del handshake");

if (stCabecera.ucType == FAIL)
{
	log(
			"ppdLog.txt",
			"PPD",
			"ERROR",
			"Error al conectar el proceso PPD con el Proceso RAID, Conexion cerrada");
} else {
	//pthread_create(&threadConsola, NULL, (void *) &consola, NULL);
	pthread_create(&threadListaPedidos, NULL, (void *) &ManejoColaPedidos,
			NULL);

	log("ppdLog.txt", "PPD", "INFO",
			"El proceso PPD se conecto correctamente con el Proceso RAID");

	//printf("Conexion exitosa con el PRAID\n");

	FD_SET( stPPD.iSocketRaid, &maestroLecturaFD);
	MAXDESC( iMaxDescriptor, stPPD.iSocketRaid);
	/*Establezco el nuevo descriptor maximo*/

	while (1) {
		cjtoTemporal = cjtoMaestro;
		stCabecera.lPayload = '0';
		memset(stCabecera.buffer, 0, sizeof(ST_SECTOR));
		/* Recibo peticion del PRAID */
		if (recv(stPPD.iSocketRaid, (void *) &stCabecera, sizeof(ST_NIPC),
				MSG_WAITALL) > 0) {
			//printf("pay: %s\n", stCabecera.szPayload);

			if (stCabecera.ucType == WRITESECTOR)
			{

				/*if (recv(stPPD.iSocketRaid, (void *) &rtaSector,
						sizeof(ST_RESPUESTA), 0) <= 0) {
					close(stPPD.iSocketRaid);
					log("ppdLog.txt", "PFD", "INFO",
							"Se cerro el socket del pfs");
					perror("error recibiendo sector");
					//return -4;
				}*/

				//printf("recibi writesector\n");
				info.TipoPedido = WRITESECTOR;
				//p=strtok(stCabecera.szPayload,"|");
				info.sector = stCabecera.sector;
				info.prioridad = 1;
				//p=strtok(NULL,"|");
				//strcpy(info.buffer, p);
				memcpy(info.buffer, stCabecera.buffer, sizeof(ST_SECTOR));

				//info.TipoPedido = WRITESECTOR;
				//p=strtok(NULL,"|");
				//strcpy(info.buffer, p);
				info.prioridad = 1;
				//printf("Nueva peticion del PRAID: Escritura del sector %d\n", info.sector);
				sprintf(mensajeLog, "Nueva peticion del PRAID: Escritura del sector %d", info.sector);
				log("ppdLog.txt", "PFD", "INFO", mensajeLog);
			} else if (stCabecera.ucType == GETSECTOR) {
				//p = strtok(stCabecera.szPayload, "|");
				//info.sector = atoi(p);
				info.sector = stCabecera.sector;
				memset(info.buffer, 0, sizeof(ST_SECTOR));
				//strcpy(info.buffer, "");
				info.TipoPedido = GETSECTOR;
				info.prioridad = 2;
				//printf("Nueva peticion del PRAID: Lectura del sector %d\n", stCabecera.sector);
				sprintf(mensajeLog, "Nueva peticion del PRAID: Lectura del sector %d", info.sector);
				log("ppdLog.txt", "PFD", "INFO", mensajeLog);
			} else if (stCabecera.ucType == SINCRO)
			{

				/*if (recv(stPPD.iSocketRaid, (void *) &rtaSector,
						sizeof(ST_RESPUESTA), 0) <= 0) {
					close(stPPD.iSocketRaid);
					log("ppdLog.txt", "PFD", "INFO",
							"Se cerro el socket del pfs");
					perror("error recibiendo sector");
					//return -4;
				}*/

				//printf("recibi writesector\n");
				info.TipoPedido = SINCRO;
				//p=strtok(stCabecera.szPayload,"|");
				info.sector = stCabecera.sector;
				info.prioridad = 1;
				//p=strtok(NULL,"|");
				//strcpy(info.buffer, p);
				memcpy(info.buffer, stCabecera.buffer, sizeof(ST_SECTOR));

				//info.TipoPedido = WRITESECTOR;
				//p=strtok(NULL,"|");
				//strcpy(info.buffer, p);
				info.prioridad = 1;
				//printf("Nueva peticion del PRAID: Escritura del sector %d\n", info.sector);
				sprintf(mensajeLog, "Nueva peticion del PRAID: Escritura del sector %d", info.sector);
				log("ppdLog.txt", "PFD", "INFO", mensajeLog);
			} else if (stCabecera.ucType == FINSINCRO)
			{
				valorRetorno=msync(stPPD.ArchivoEnDisco, stPPD.filesize, MS_SYNC);
				if(valorRetorno==-1)
						perror("Error msync");
				continue;
			}
			pthread_mutex_lock(&mutex1);
			info.socketPedido = stPPD.iSocketRaid;
			if (strcmp(stPPD.cAlgoritmo, "SSTF") == 0) {
				if (CargoElementoEnLista(info) != 0) {
					//printf("Error al cargar el elemento en la lista\n");
					log("ppdLog.txt", "PFD", "ERROR", "Error al cargar el elemento en la lista");
				}
			} else {
				if (CargoElementoEnListaNStep(info) != 0) {
					//printf("Error al cargar el elemento en la lista\n");
					log("ppdLog.txt", "PFD", "ERROR", "Error al cargar el elemento en la lista");
					//CargoElementoEnListaAlFinalNStep();
					//CargoElementoEnListaNStep(info);
				}
			}

			pthread_mutex_unlock(&mutex1);
			sem_post(&sem_pedidos);
		}
	}
	free(mensajeLog);
	shutdown(stPPD.iSocketRaid, SHUT_RDWR);
	close(stPPD.iSocketRaid);
}
return 0;
}

void consola(void *parametroSinUso) {
fd_set maestroLecturaFD, descLecturaFD; //, maestroEscrituraFD, descEscrituraFD;
//int				iRtaSelect, i = 0;
int iMaxDescriptor = 0;
int len, sockEscucha;
struct sockaddr_un local, remote;
socklen_t len_structura;
ST_NIPC stCabecera;
ST_PEDIDOS_INFO info;
ST_RESPUESTA rtaSector;
char *p;
//char *token;
char *pathConect;
char *mensajeLog;
mensajeLog = (char *) malloc(sizeof(char) * 250);

pathConect = (char *) malloc(sizeof(char) * 500);
sprintf(pathConect, "%s/connect_socket", stPPD.szPathConsola);
//printf("Path: %s\n", pathConect);

if ((sockEscucha = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
	perror("Error al intentar crear el socket de consola");
	log("ppdLog.txt", "PPD", "ERROR",
			"Error al intentar crear el socket de consola");
}

local.sun_family = AF_UNIX;
strcpy(local.sun_path, pathConect);
unlink(local.sun_path);
len = strlen(local.sun_path) + sizeof(local.sun_family);
if (bind(sockEscucha, (struct sockaddr *) &local, len) == -1) {
	perror("Error al intentar hacer bind");
	log("ppdLog.txt", "PPD", "ERROR", "Error al intentar hacer bind");
}

if (listen(sockEscucha, 5) == -1) {
	perror("Error en el listen\n");
	log("ppdLog.txt", "PPD", "ERROR", "Error en el listen");
}

//while(1)
//{
//	pthread_mutex_unlock(&global_mutex);
len_structura = sizeof(struct sockaddr);

cpid = fork();
if (cpid == 0) {
	char *args[] = { "PConsola", NULL };

	if (execv((char*)parametroSinUso, args) == -1)
		perror("error: ");
	//printf("Error en execv\n");
} else {
	if (cpid == -1)
		printf("Error en fork\n");
}
if ((stPPD.iSocketConsola = accept((char) sockEscucha,
		(struct sockaddr *) &remote, &len_structura)) == -1) {
	//printf("Error en el acept \n");
	log("ppdLog.txt", "PPD", "ERROR", "Error en el acept ");
} //else
//printf("Conexion aceptada\n");

if (recv(stPPD.iSocketConsola, (void *) &stCabecera, sizeof(ST_NIPC),
		MSG_WAITALL) < 0) {
	close(stPPD.iSocketConsola);
	perror("error recv");
	log("ppdLog.txt", "PFD", "ERROR", "Al recibir Mensaje de nueva conexion");
	//return -4;
}
//printf("ucType: %u\n",stCabecera.ucType);
//printf("Antes de enviar respuesta al handshake\n");
if (stCabecera.ucType == HANDSHAKE) {
	//printf("Recibi pedido de handshake\n");
	stCabecera.ucType = PPD;
	stCabecera.lPayload = 0;

	if (send(stPPD.iSocketConsola, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL)
			< 0) {
		close(stPPD.iSocketConsola);
		log("ppdLog.txt", "PPD", "ERROR", "Al enviar respuesta HandShake");
		//return -3;
	} else
		log("ppdLog.txt", "PPD", "INFO", "Se conectó con la consola");
	/* EN CASO DE ERROR CARGAR stCabecera.ucType CON FAIL Y ENVIAR */
}

FD_SET( stPPD.iSocketConsola, &maestroLecturaFD);
MAXDESC( iMaxDescriptor, stPPD.iSocketConsola);
/*Establezco el nuevo descriptor maximo*/

while (1) {
	descLecturaFD = maestroLecturaFD;
	while (select(iMaxDescriptor + 1, &descLecturaFD, NULL, NULL, NULL) == -1);

	if (recv(stPPD.iSocketConsola, (void *) &stCabecera, sizeof(ST_NIPC), MSG_WAITALL) < 0) {
		close(stPPD.iSocketConsola);
		log("ppdLog.txt", "PFD", "INFO", "Se cerro el socket de la consola");
		pthread_exit(NULL);
	}

	//printf("pay: %s\n", stCabecera.szPayload);
	//info.sector=atoi(p);

	switch (stCabecera.ucType) {
	case INFO:
		info.TipoPedido = INFO;
		//p = strtok(stCabecera.szPayload, "|");
		log("ppdLog.txt", "PPD", "INFO", "Nueva peticion de la consola: posicion actual del cabezal");
		//printf("Recibi pedido  de la consola: posicion actual del cabezal\n");

		stCabecera.ucType = INFOOK;
		//printf("Posicion actual: %d\n", stPPD.sectorActual);
		//sprintf(stCabecera.buffer, "%d", stPPD.sectorActual);
		memset(stCabecera.buffer, 0, sizeof(ST_SECTOR));
		stCabecera.sector = stPPD.sectorActual;
		stCabecera.lPayload = sizeof(ST_SECTOR);
		//printf("Envio respuesta a la consola de INFO %d\n", stCabecera.sector);
		if (send(stPPD.iSocketConsola, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL) < 0)
			log("ppdLog.txt", "PPD", "ERROR", "Error al enviar posicion actual de cabezal");
		else
			log("ppdLog.txt", "PPD", "INFO", "Envie posicion actual de cabezal");

		//printf("Envie correctamente INFO \n");

		break;

	case CLEAN:

//		if (recv(stPPD.iSocketConsola, (void *) &rtaSector,
//				sizeof(ST_RESPUESTA), MSG_WAITALL) < 0) {
//			close(stPPD.iSocketConsola);
//			log("ppdLog.txt", "PFD", "INFO", "Se cerro el socket del pfs");
//			perror("error recibiendo sector");
//			pthread_exit(NULL);
//		}

		info.socketPedido = stPPD.iSocketConsola;
		info.prioridad = 1;
		//printf("LLego cleansector\n");
		info.TipoPedido = WRITESECTOR;
		//p=strtok(stCabecera.szPayload,"|");
		//p=strtok(stCabecera.szPayload,"|");
		info.sector = stCabecera.sector;
		memset(info.buffer, 0, sizeof(ST_SECTOR));

		sprintf(mensajeLog,	"Nueva peticion de la consola: Escribir en sector %d", info.sector);
		log("ppdLog.txt", "PFD", "INFO", mensajeLog);
		pthread_mutex_lock(&mutex1);
		if (strcmp(stPPD.cAlgoritmo, "SSTF") == 0) {
			if (CargoElementoEnLista(info) != 0) {
				//printf("Error al cargar el elemento en la lista\n");
				log("ppdLog.txt", "PFD", "ERROR", "Error al cargar el elemento en la lista");
			}
		} else {
			if (CargoElementoEnListaNStep(info) != 0) {
				//printf("Error al cargar el elemento en la lista\n");
				log("ppdLog.txt", "PFD", "ERROR", "Error al cargar el elemento en la lista");
				//CargoElementoEnListaAlFinalNStep();
				//CargoElementoEnListaNStep(info);
			}
		}
		pthread_mutex_unlock(&mutex1);
		sem_post(&sem_pedidos);

		break;
	case TRACE:
		//printf("Nueva peticion de la consola: TRACE\n");
		info.TipoPedido = TRACE;
		//p = strtok(stCabecera.szPayload, "|");
		info.prioridad = 0;
		//p=strtok(stCabecera.szPayload,"|");
		info.sector = stCabecera.sector;
		strcpy(info.buffer, "");
		info.socketPedido = stPPD.iSocketConsola;
		//log( "ppdLog.txt", "PFD", "INFO","Nueva peticion de la consola: GETSector");
		sprintf(mensajeLog, "Nueva peticion de la consola: Lectura del sector %d", info.sector);
		log("ppdLog.txt", "PFD", "INFO", mensajeLog);
		pthread_mutex_lock(&mutex1);
		if (strcmp(stPPD.cAlgoritmo, "SSTF") == 0) {
			if (CargoElementoEnLista(info) != 0) {
				//printf("Error al cargar el elemento en la lista\n");
				log("ppdLog.txt", "PFD", "ERROR", "Error al cargar el elemento en la lista");
			}
		} else {
			if (CargoElementoEnListaNStep(info) != 0) {
				//printf("Error al cargar el elemento en la lista\n");
				log("ppdLog.txt", "PFD", "ERROR", "Error al cargar el elemento en la lista");
				//CargoElementoEnListaAlFinalNStep();
				//CargoElementoEnListaNStep(info);
			}
		}
		pthread_mutex_unlock(&mutex1);
		sem_post(&sem_pedidos);

		break;

	case WRITESECTOR:
		/*info.TipoPedido = WRITESECTOR;
		 info.prioridad = 1;
		 //p=strtok(stCabecera.szPayload,"|");
		 info.sector= atoi(p);
		 p=strtok(NULL,"|");
		 strcpy(info.buffer, p);
		 */
//		if (recv(stPPD.iSocketConsola, (void *) &rtaSector,
//				sizeof(ST_RESPUESTA), MSG_WAITALL) < 0) {
//			close(stPPD.iSocketConsola);
//			log("ppdLog.txt", "PFD", "INFO", "Se cerro el socket del pfs");
//			perror("error recibiendo sector");
//			pthread_exit(NULL);
//		}
		//printf("LLego writesector\n");
		info.TipoPedido = WRITESECTOR;
		info.sector = stCabecera.sector;
		info.prioridad = 1;
		memcpy(info.buffer, stCabecera.buffer, sizeof(ST_SECTOR));
		info.socketPedido = stPPD.iSocketConsola;
		//log( "ppdLog.txt", "PFD", "INFO","Nueva peticion de la consola: Write en sector");
		sprintf(mensajeLog, "Nueva peticion de la consola: Escribir en sector %d", info.sector);
		log("ppdLog.txt", "PFD", "INFO", mensajeLog);
		pthread_mutex_lock(&mutex1);
		if (strcmp(stPPD.cAlgoritmo, "SSTF") == 0) {
			if (CargoElementoEnLista(info) != 0) {
				//printf("Error al cargar el elemento en la lista\n");
				log("ppdLog.txt", "PFD", "ERROR", "Error al cargar el elemento en la lista");
			}
		} else {
			if (CargoElementoEnListaNStep(info) != 0) {
				//printf("Error al cargar el elemento en la lista\n");
				log("ppdLog.txt", "PFD", "ERROR", "Error al cargar el elemento en la lista");
				//CargoElementoEnListaAlFinalNStep();
				//CargoElementoEnListaNStep(info);
			}
		}
		pthread_mutex_unlock(&mutex1);
		sem_post(&sem_pedidos);

		break;
	case GETSECTOR:
		info.TipoPedido = GETSECTOR;
//		p = strtok(stCabecera.szPayload, "|");
		info.prioridad = 0;
		//p=strtok(stCabecera.szPayload,"|");
//		info.sector = atoi(p);
		info.sector = stCabecera.sector;
		strcpy(info.buffer, "");
		info.socketPedido = stPPD.iSocketConsola;
		//log( "ppdLog.txt", "PFD", "INFO","Nueva peticion de la consola: GETSector");
		sprintf(mensajeLog,	"Nueva peticion de la consola: Lectura del sector %d", info.sector);
		log("ppdLog.txt", "PFD", "INFO", mensajeLog);
		pthread_mutex_lock(&mutex1);
		if (strcmp(stPPD.cAlgoritmo, "SSTF") == 0) {
			if (CargoElementoEnLista(info) != 0) {
				//printf("Error al cargar el elemento en la lista\n");
				log("ppdLog.txt", "PFD", "ERROR", "Error al cargar el elemento en la lista");
			}
		} else {
			if (CargoElementoEnListaNStep(info) != 0) {
				//printf("Error al cargar el elemento en la lista\n");
				log("ppdLog.txt", "PFD", "ERROR", "Error al cargar el elemento en la lista");
				//CargoElementoEnListaAlFinalNStep();
				//CargoElementoEnListaNStep(info);
			}
		}
		pthread_mutex_unlock(&mutex1);
		sem_post(&sem_pedidos);

		break;
	case CERRADO:
		log("ppdLog.txt", "PPD", "INFO", "La consola se cerro");
		printf("La consola se cerro\n");
		finPPD();
		pthread_exit(NULL);
		break;
	case TLECTURA:
		stPPD.iTiempoLectura = (float)stCabecera.sector / 1000;
		break;
	case TESCRITURA:
		stPPD.iTiempoEscritura = (float)stCabecera.sector / 1000;
		break;
	}

	//}
}
free(pathConect);
free(mensajeLog);
pthread_exit(NULL);
}

void ManejoColaPedidos(void *parametroSinUso) {
//fd_set				maestroLecturaFD, descLecturaFD, maestroEscrituraFD, descEscrituraFD;
int i = 0;
//int 				iMaxDescriptor=0;
//int 				file, len, sockEscucha;
//struct 				sockaddr_un local, remote;
//socklen_t 			len_structura;
ST_NIPC stCabecera;
ST_PEDIDOS_INFO info, info2;
//char* sectorObtenido=(char*)malloc(512);
ST_PEDIDOS *p;
ST_PEDIDOS_NSTEP *pListaNStep, *pAux, *q;
;
int32_t SectorActual, SectorInicial, SectorFinal;
int sectorAvance = 0;
char *token;
int rta = 0;
//ST_SECTOR			*unSector;
ST_RESPUESTA rtaSector;
char *mensajeLog;
mensajeLog = (char *) malloc(sizeof(char) * 250);
//char *sectoresPendientes = (char *) malloc(sizeof(char) * 1000000);

//p = (ST_PEDIDOS *) malloc(sizeof(ST_PEDIDOS));
//pListaNStep = (ST_PEDIDOS_NSTEP *) malloc(sizeof(ST_PEDIDOS_NSTEP));
//token=(char *)malloc(sizeof(char));
while (1) {

	sem_wait(&sem_pedidos);
	//printf("Tengo pedidos, busco cual respondo \n");
	if (strcmp(stPPD.cAlgoritmo, "SSTF") == 0) {
		if (listaPedidos!=NULL)
		{
		//	printf("LA LISTA NO ESTA VACIA!\n");
		//printf("cantidad pedidos pendientes: %d\n", cantidadPedidos(&listaPedidos));
		//p=listaPedidos;

			//sectoresPedidos();
			//printf("Estoy revisando la lista de pedidos!\n");
			pthread_mutex_lock(&mutex1);

			info = trabajoListaPedidosSSTF();
			//	printf("voy a eliminar el sector: %i!\n",info.sector);
			//printf("Sector a buscar: %d\n", info.sector);
			i = EliminoElemento(info);
			//sectoresPedidos();
			//info2 = BuscoProximoSectorSSTF();
			//printf("atendido sector %d de socket %d\n", info.sector,info.socketPedido);
			//sectoresPedidos(&sectoresPendientes);
			pthread_mutex_unlock(&mutex1);

			stPPD.enSincro = 0;
			switch (info.TipoPedido) {
			case GETSECTOR: //LEER SECTOR
				SectorActual = stPPD.sectorActual;
				stCabecera.ucType = RTASECTOR;
				leerSector(&stCabecera, info.sector);
				//strcpy(stCabecera.szPayload, unSector);
				//printf("Buffer: %u\n", unSector);
				stCabecera.ucType = RTASECTOR;
				stCabecera.sector = info.sector;
				//stCabecera.lPayload = strlen(stCabecera.szPayload);
				break;
			case WRITESECTOR: //ESCRIBIR SECTOR
				printf("escribi sector\n");
				SectorActual = stPPD.sectorActual;
				stCabecera.lPayload = 0;
				if ((i = EscribirSector(info.buffer, info.sector)) == 0)
					stCabecera.ucType = WRITESECTOROK;
				else
					stCabecera.ucType = FAIL;
				memset(stCabecera.buffer,0, sizeof(ST_SECTOR));
				break;
			case SINCRO:
				SectorActual = stPPD.sectorActual;
				stCabecera.lPayload = 0;
				stPPD.enSincro = 1;
				if ((i = EscribirSector(info.buffer, info.sector)) == 0)
					stCabecera.ucType = WRITESECTOROK;
				else
					stCabecera.ucType = FAIL;
				memset(stCabecera.buffer,0, sizeof(ST_SECTOR));
				break;
			case CLEAN:
				//printf("Pedido: %s\n", info.buffer);
				token = strtok(info.buffer, "|");
				SectorInicial = atoi(token);
				token = strtok(NULL, "|");
				sectorAvance = atoi(token);
				SectorFinal = SectorInicial + sectorAvance;
				//printf("Sector inicial: %d\n", SectorInicial);
				//printf("Sector Avance: %d\n", sectorAvance);
				//sprintf("Sector final: %d\n", SectorFinal);
				//memset(info.buffer, '\0', sizeof(info.buffer));
				//for (i=SectorInicial; SectorFinal >= i; i ++ )
				//{
				//	SectorActual=(int32_t)i;
				//rta = EscribirSector(info.buffer, i);
				//}
				stCabecera.lPayload = 0;
				if (rta == 0)
					stCabecera.ucType = CLEANOK;
				else
					stCabecera.ucType = FAIL;

				break;
			case TRACE:
				//printf("Proximo sector: %d\n", info2.sector);
				SectorActual = stPPD.sectorActual;
				stCabecera.ucType = RTASECTOR;
				leerSector(&stCabecera, info.sector);
				//strcpy(stCabecera.szPayload, unSector);
				//printf("Buffer: %u\n", unSector);
				stCabecera.ucType = RTASECTOR;
				stCabecera.sector = info.sectorProximo;
				//stCabecera.lPayload = strlen(stCabecera.szPayload);
				break;
			}
			if ((info.TipoPedido == GETSECTOR) || (info.TipoPedido == TRACE)) {
				stCabecera.ucType = RTASECTOR;
				//memset(stCabecera.buffer, 0, sizeof(ST_SECTOR));
				stCabecera.lPayload = sizeof(ST_SECTOR);
				if (send(info.socketPedido, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL) < 0) {

					log("ppdLog.txt", "PPD", "ERROR", "Error al enviar respuesta");
					//printf("Error al enviar respuesta de lectura\n");
					perror("send");

				}else
				{
					sprintf(mensajeLog,"Envie respuesta de lectura del sector %d",info.sector);
					log("ppdLog.txt", "PFD", "INFO", mensajeLog);
					//log("ppdLog.txt", "PPD", "INFO", "Envie respuesta");
					loguear(SectorActual, info.sector, info.sectorProximo, info.subiendo);
				}

				/*if (send(info.socketPedido, &rtaSector, sizeof(ST_RESPUESTA),
						MSG_NOSIGNAL) < 0) {
					log("ppdLog.txt", "PPD", "ERROR",
							"Error al enviar respuesta");
					//printf("Error al enviar respuesta de lectura\n");
					perror("send");
				} else {
					log("ppdLog.txt", "PPD", "INFO", "Envie respuesta");
					loguear(SectorActual, info.sector, info.sector);
					//printf("Envie respuesta de lectura del sector %d\n", info.sector);
				}*/
				//printf("Sector actual: %d\n", stPPD.sectorActual);
			} else if (info.TipoPedido != SINCRO){
				if (send(info.socketPedido, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL) < 0)
					log("ppdLog.txt", "PPD", "ERROR", "Error al enviar respuesta");
				else {
					sprintf(mensajeLog,"Envie respuesta de escritura del sector %d",info.sector);
					log("ppdLog.txt", "PFD", "INFO", mensajeLog);
					//log("ppdLog.txt", "PPD", "INFO", "Envie respuesta");
					loguear(SectorActual, info.sector, info.sectorProximo, info.subiendo);
				}
			}
			//printf("envie respuesta de pedido del sector %d \n", info.sector);
			//sectoresPedidos();
			//p=p->sgte;
		}

	} else {
		//Trabajo pedidos N-STEP-SCAN
		pListaNStep = listaPedidosNStep;
		while (pListaNStep != NULL) {
			//printf("hay nodos\n");
			if (pListaNStep->CantNodosRealizados < pListaNStep->CantNodosSublistas) {
				//printf("hay pedidos disponibles\n");
				//p = pListaNStep->SubLista;
				//while (p != NULL) {

					pthread_mutex_lock(&mutex1);

					info = trabajoListaPedidosNStep(pListaNStep->SubLista);
					//i = EliminoElemento(&pListaNStep->SubLista, info.sector, info.TipoPedido );
					//i = EliminoElementoNStep(pListaNStep->SubLista, info);
					pListaNStep->CantNodosRealizados++;

					pthread_mutex_unlock(&mutex1);
					//printf("Sector: %d\n", info.sector);
					//printf("sublista: %d Realizados: %d\n", pListaNStep->CantNodosSublistas, pListaNStep->CantNodosRealizados);
					//sectoresPedidosNSTEP();

					switch (info.TipoPedido)
					{
						case GETSECTOR: //LEER SECTOR
							SectorActual = stPPD.sectorActual;
							stCabecera.ucType = RTASECTOR;
							leerSector(&stCabecera, info.sector);
							//strcpy(stCabecera.szPayload, unSector);
							//printf("Buffer: %u\n", unSector);
							stCabecera.ucType = RTASECTOR;
							stCabecera.sector = info.sector;
							//stCabecera.lPayload = strlen(stCabecera.szPayload);
							break;
						case WRITESECTOR: //ESCRIBIR SECTOR
							SectorActual = stPPD.sectorActual;
							stCabecera.lPayload = 0;
							if ((i = EscribirSector(info.buffer, info.sector)) == 0)
								stCabecera.ucType = WRITESECTOROK;
							else
								stCabecera.ucType = FAIL;
							memset(stCabecera.buffer, 0, sizeof(ST_SECTOR));
							break;
						case CLEAN:
							//printf("Pedido: %s\n", info.buffer);
							token = strtok(info.buffer, "|");
							SectorInicial = atoi(token);
							token = strtok(NULL, "|");
							sectorAvance = atoi(token);
							SectorFinal = SectorInicial + sectorAvance;
							//printf("Sector inicial: %d\n", SectorInicial);
							//printf("Sector Avance: %d\n", sectorAvance);
							//sprintf("Sector final: %d\n", SectorFinal);
							memset(stCabecera.buffer, 0, sizeof(ST_SECTOR));
							for (i = SectorInicial; SectorFinal >= i; i++) {
								SectorActual = (int32_t) i;
								rta = EscribirSector(info.buffer, i);
							}
							stCabecera.lPayload = 0;
							if (rta == 0)
								stCabecera.ucType = CLEANOK;
							else
								stCabecera.ucType = FAIL;

							break;
						case TRACE:
							leerSector(&stCabecera, info.sector);
							//sprintf(stCabecera.szPayload, "%d|",
							//		stPPD.sectorActual);
							stCabecera.sector = stPPD.sectorActual;
							memset(stCabecera.buffer, 0, sizeof(ST_SECTOR));
							stCabecera.lPayload = sizeof(stCabecera.buffer);
							if (i != 0)
								stCabecera.ucType = TRACEOK;
							else
								stCabecera.ucType = FAIL;

							break;
					}

					if (info.TipoPedido == GETSECTOR)
					{
						stCabecera.ucType = RTASECTOR;
						//memset(stCabecera.szPayload, "");
						stCabecera.lPayload = sizeof(ST_SECTOR);
						if (send(info.socketPedido, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL) < 0) {
							log("ppdLog.txt", "PPD", "ERROR", "Error al enviar respuesta");
							perror("send");
						}else
						{
							sprintf(mensajeLog,"Envie respuesta de lectura del sector %d",info.sector);
							log("ppdLog.txt", "PFD", "INFO", mensajeLog);
							//log("ppdLog.txt", "PPD", "INFO", "Envie respuesta");
							loguear(SectorActual, info.sector, info.sectorProximo, info.subiendo);
						}

						/*if (send(info.socketPedido, &rtaSector,
								sizeof(ST_RESPUESTA), MSG_NOSIGNAL) < 0) {

						} else {
							log("ppdLog.txt", "PPD", "INFO", "Envie respuesta");
							loguear(SectorActual, info.sector, info2.sector);
							//printf("Envie respuesta de lectura del sector %d\n", info.sector);
						}*/
						//printf("Sector actual: %d\n", stPPD.sectorActual);
					} else {
						if (send(info.socketPedido, &stCabecera,
								sizeof(ST_NIPC), MSG_NOSIGNAL) < 0)
							log("ppdLog.txt", "PPD", "ERROR",
									"Error al enviar respuesta");
						else {
							sprintf(mensajeLog,"Envie respuesta de escritura del sector %d",info.sector);
							log("ppdLog.txt", "PFD", "INFO", mensajeLog);
							//log("ppdLog.txt", "PPD", "INFO", "Envie respuesta");
							loguear(SectorActual, info.sector, info.sectorProximo, info.subiendo);
						}
					}
				//	p = p->sgte;
				//}
			} else {
				if (pListaNStep->sgte == NULL)
				{
					pListaNStep = NULL;
				} else {
					q = p;
					pListaNStep = pListaNStep->sgte;
					//sectoresPedidosNSTEP();
					free(q);
				}
			}
		}
	}

}
//free(p);
//free(pListaNStep);

pthread_exit(NULL);
}

void finPPD(void) {
ST_NIPC stCabecera;
int32_t filesize;
char *msj = (char *) malloc(sizeof(char) * 500);
printf("Se cierra el PPD\n");

//filesize = tamanioDisco();
msync(stPPD.ArchivoEnDisco, stPPD.filesize, MS_SYNC);

if (stPPD.iSocketConsola > 0) {
	stCabecera.lPayload = 0;
	//strcpy(stCabecera.szPayload, "");
	memset(stCabecera.buffer, 0, sizeof(ST_SECTOR));
	stCabecera.ucType = PPDCERRADO;
	if (send(stPPD.iSocketConsola, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL)
			< 0)
		log("ppdLog.txt", "PPD", "ERROR",
				"al enviar informacion a consola que se cerro el PPD");
	else
		log("ppdLog.txt", "PPD", "INFO",
				"envie informacion a consola que se cerro el PPD");
}

//if (stPPD.iSocketRaid > 0) {
//	stCabecera.lPayload = 0;
//	//strcpy(stCabecera.szPayload, "");
//	memset(stCabecera.buffer, 0, sizeof(ST_SECTOR));
//	stCabecera.ucType = PPDCERRADO;
//	if (send(stPPD.iSocketRaid, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL) < 0)
//		log("ppdLog.txt", "PPD", "ERROR",
//				"al enviar informacion a RAID que se cerro el PPD");
//	else
//		log("ppdLog.txt", "PPD", "INFO",
//				"envie informacion a RAID que se cerro el PPD");
//}

log("ppdLog.txt", "PPD", "INFO", "se cerro el PPD");
sprintf(msj, "kill -9 %d", cpid);
cerrarDisco();
//kill(cpid);
system(msj);
/*---  CERRAR SOCKETS  ---*/
free(listaPedidos);
free(listaPedidosNStep);

exit(0);
}

void Pruebas() {
ST_PEDIDOS_INFO info, info2;
int i = 0;
stPPD.sectorActual = 0;
ST_PEDIDOS *p;
ST_PEDIDOS_NSTEP *pListaNStep, *pAux, *q;
//printf("Adentro de pruebas\n");
//pthread_create(&threadListaPedidos, NULL, (void *) &ManejoColaPedidos, NULL);

info.TipoPedido = GETSECTOR;
memset(info.buffer, 0, sizeof(ST_SECTOR));
info.sector = 15;
info.socketPedido = 1;
info.prioridad = 0;
if (strcmp(stPPD.cAlgoritmo, "SSTF") == 0)
	CargoElementoEnLista(info);
else
	CargoElementoEnListaNStep(info);
//printf("Cargo un elemento\n");
info.TipoPedido = GETSECTOR;
memset(info.buffer, 0, sizeof(ST_SECTOR));
info.sector = 7;
info.socketPedido = 1;
info.prioridad = 0;
if (strcmp(stPPD.cAlgoritmo, "SSTF") == 0)
	CargoElementoEnLista(info);
else
	CargoElementoEnListaNStep(info);

info.TipoPedido = GETSECTOR;
memset(info.buffer, 0, sizeof(ST_SECTOR));
info.sector = 18;
info.socketPedido = 1;
info.prioridad = 0;
if (strcmp(stPPD.cAlgoritmo, "SSTF") == 0)
	CargoElementoEnLista(info);
else
	CargoElementoEnListaNStep(info);

info.TipoPedido = GETSECTOR;
memset(info.buffer, 0, sizeof(ST_SECTOR));
info.sector = 21;
info.socketPedido = 1;
info.prioridad = 0;
if (strcmp(stPPD.cAlgoritmo, "SSTF") == 0)
	CargoElementoEnLista(info);
else
	CargoElementoEnListaNStep(info);

info.TipoPedido = GETSECTOR;
memset(info.buffer, 0, sizeof(ST_SECTOR));
info.sector = 30;
info.socketPedido = 1;
info.prioridad = 0;
if (strcmp(stPPD.cAlgoritmo, "SSTF") == 0)
	CargoElementoEnLista(info);
else
	CargoElementoEnListaNStep(info);

info.TipoPedido = GETSECTOR;
memset(info.buffer, 0, sizeof(ST_SECTOR));
info.sector = 8;
info.socketPedido = 1;
info.prioridad = 0;
if (strcmp(stPPD.cAlgoritmo, "SSTF") == 0)
	CargoElementoEnLista(info);
else
	CargoElementoEnListaNStep(info);

info.TipoPedido = GETSECTOR;
memset(info.buffer, 0, sizeof(ST_SECTOR));
info.sector = 18;
info.socketPedido = 1;
info.prioridad = 0;
if (strcmp(stPPD.cAlgoritmo, "SSTF") == 0)
	CargoElementoEnLista(info);
else
	CargoElementoEnListaNStep(info);

info.TipoPedido = GETSECTOR;
memset(info.buffer, 0, sizeof(ST_SECTOR));
info.sector = 10;
info.socketPedido = 1;
info.prioridad = 0;
if (strcmp(stPPD.cAlgoritmo, "SSTF") == 0)
	CargoElementoEnLista(info);
else
	CargoElementoEnListaNStep(info);

//printf("Sector: ");
//sectoresPedidos();
if (strcmp(stPPD.cAlgoritmo, "SSTF") == 0) {
	while (listaPedidos != NULL) {
		pthread_mutex_lock(&mutex1);

		info = trabajoListaPedidosSSTF();
		//	printf("voy a eliminar el sector: %i!\n",info.sector);
		//printf("Sector a buscar: %d\n", info.sector);
		i = EliminoElemento(info);
		info2 = BuscoProximoSectorSSTF();
		pthread_mutex_unlock(&mutex1);

//		if (info2.sector > -1)
////			printf("Proximo sector: %d\n", info2.sector);
//		else
//			printf("Proximo sector: \n");
		//sectoresPedidos();
	}
} else {
	//Trabajo pedidos N-STEP-SCAN
	//sectoresPedidosNSTEP();
	pListaNStep = listaPedidosNStep;
	pAux = NULL;
	q = NULL;

	while (pListaNStep != NULL) {
		//sectoresPedidosNSTEP();
		if (pListaNStep->CantNodosRealizados
				< pListaNStep->CantNodosSublistas) {
			p = pListaNStep->SubLista;

			while (p != NULL) {
				pthread_mutex_lock(&mutex1);

				info = trabajoListaPedidosNStep(pListaNStep->SubLista);
				//i = EliminoElemento(&pListaNStep->SubLista, info.sector, info.TipoPedido );
				//i = EliminoElementoNStep(pListaNStep->SubLista, info);
				pListaNStep->CantNodosRealizados++;

				pthread_mutex_unlock(&mutex1);

				printf("Sector a buscar: %d\n", info.sector);

				if (stPPD.sectorActual < info.sector)
					stPPD.sectorActual = info.sector + 1;
				else
					stPPD.sectorActual = info.sector - 1;

				p = p->sgte;
			}
		} else {
			if (pListaNStep->sgte == NULL)
			{
				pListaNStep = NULL;
			} else {
				q = p;
				pListaNStep = pListaNStep->sgte;
				//sectoresPedidosNSTEP();
				free(q);
			}
		}

		//EliminoElementoNStep();
	}
	free(p);
	free(pListaNStep);
}
}

int main2(int argc, char *argv[]) {

size_t filesize;
int file; //, len, sockEscucha;
//struct sockaddr_un local, remote;
float tiempo = 0;
//signal(SIGINT, exeConsola);
system("clear");

signal(SIGINT, finPPD);
cargarConfiguracion(&stPPD);

stPPD.iSocketEscucha = 0;
stPPD.sectorActual = 0;

printf(
		"=====================================================================\n");
printf("\t\t Proceso de Prueba del PPD\n");
printf(
		"=====================================================================\n\n");

stPPD.sectoresTotales = (int) stPPD.iCilindro * (int) stPPD.iSector;

tiempo = 60000 / (int) stPPD.iRPM;
stPPD.tiempoEntreSectores = tiempo / stPPD.sectoresTotales;

stPPD.iTiempoEscritura = stPPD.iTiempoEscritura / 1000;
stPPD.iTiempoLectura = stPPD.iTiempoLectura / 1000;
Pruebas();

printf("Fin del proceso\n\n");
log("ppdLog.txt", "PPD", "INFO", "Se cerró el proceso PPD");

return 0;
}

int cerrarDisco()
{
	return munmap(stPPD.ArchivoEnDisco, stPPD.filesize);
}
